package com.example.springboot_demo.weixin.utils;

import com.example.springboot_demo.weixin.entity.*;
import com.example.springboot_demo.weixin.message.*;
import com.thoughtworks.xstream.XStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.*;

/**
 * 微信消息处理工具类
 */
public class MessageUtil {

    private static final String MESSAGE_TEXT = "text";
    private static final String MESSAGE_NEWS = "news";
    private static final String MESSAGE_IMAGE = "image";
    private static final String MESSAGE_VOICE = "voice";
    private static final String MESSAGE_VIDEO = "video";
    private static final String MESSAGE_MUSIC = "music";
    private static final String MESSAGE_THUMB = "thumb";

    /**
     * 将微信的请求中参数转成map集合
     *
     * @param request
     * @return
     */
    public static Map<String, String> xmlToMap(HttpServletRequest request) {
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        InputStream in = null;
        try {
            in = request.getInputStream();
            Document document = reader.read(in);
            Element root = document.getRootElement();
            List<Element> list = root.elements();
            //将每个元素的名称作为键，内容作为值放入map中
            list.forEach(element -> map.put(element.getName(), element.getText()));

        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    /**
     * 将发送消息封装成对应的xml格式
     */
    public static String textMessageToxml(TextMessage message) {
        XStream xstream = new XStream();
        xstream.alias("xml", message.getClass());
        return xstream.toXML(message);
    }

    /**
     * 封装发送文本消息对象,封装时，需要将调换发送者和接收者的关系
     *
     * @param FromUserName
     * @param ToUserName
     * @param content      消息内容
     */
    public static String initTextMessage(String FromUserName, String ToUserName, String content) {
        TextMessage text = new TextMessage();
        text.setToUserName(FromUserName);
        text.setFromUserName(ToUserName);
        text.setContent(content);
        text.setCreateTime(new Date().getTime());
        text.setMsgType(MESSAGE_TEXT);
        return textMessageToxml(text);
    }

    /**
     * 将发送图文消息封装成对应的xml格式
     *
     * @param newsMessage 图文消息
     * @return
     */
    public static String newsMessageToxml(NewsMessage newsMessage) {
        XStream xstream = new XStream();
        xstream.alias("xml", newsMessage.getClass());
        xstream.alias("item", new News().getClass());
        return xstream.toXML(newsMessage);
    }

    /**
     * 封装图文消息
     *
     * @param FromUserName
     * @param ToUserName
     * @return
     */
    public static String initNewsMessage(String FromUserName, String ToUserName) {
        String message = null;
        List<News> newsList = new ArrayList<>();
        NewsMessage newsMessage = new NewsMessage();

        News news = new News();
        news.setDescription("我的微信测试公众号");
        news.setTitle("hzp-测试号");
        news.setPicUrl("http://vison.free.ngrok.cc/images/13.jpg");
        news.setUrl("http://www.baidu.com");
        newsList.add(news);

        newsMessage.setFromUserName(ToUserName);
        newsMessage.setToUserName(FromUserName);
        newsMessage.setCreateTime(new Date().getTime());
        newsMessage.setMsgType(MESSAGE_NEWS);
        newsMessage.setArticles(newsList);
        newsMessage.setArticleCount(newsList.size());

        message = newsMessageToxml(newsMessage);
        return message;
    }

    /**
     * 将图片信息转为xml格式
     */
    public static String imageMessageToxml(ImageMessage imageMessage) {
        XStream xtream = new XStream();
        xtream.alias("xml", imageMessage.getClass());
        xtream.alias("image", new Image().getClass());
        return xtream.toXML(imageMessage);
    }

    /**
     * 封装图片消息
     *
     * @param FromUserName 发送者
     * @param ToUserName   接受者
     * @param path         图片地址
     * @return
     */
    public static String initImageMessage(String FromUserName, String ToUserName, String path) {
        Image image = new Image();
        image.setMediaId(getMediaId(path, MESSAGE_IMAGE));
        ImageMessage message = new ImageMessage();
        message.setFromUserName(ToUserName);
        message.setToUserName(FromUserName);
        message.setCreateTime(new Date().getTime());
        message.setImage(image);
        message.setMsgType(MESSAGE_IMAGE);
        return imageMessageToxml(message);
    }

    /**
     * 将语音信息转为xml格式
     *
     * @param voiceMessage 语音消息
     */
    public static String voiceMessageToxml(VoiceMessage voiceMessage) {
        XStream xtream = new XStream();
        xtream.alias("xml", voiceMessage.getClass());
        xtream.alias("Voice", new Voice().getClass());
        return xtream.toXML(voiceMessage);
    }

    /**
     * 封装语音消息
     *
     * @param FromUserName 发送者
     * @param ToUserName   接受者
     * @param path         语音地址
     * @return
     */
    public static String initVoiceMessage(String FromUserName, String ToUserName, String path) {
        Voice voice = new Voice();
        voice.setMediaId(getMediaId(path, MESSAGE_VOICE));
        VoiceMessage message = new VoiceMessage();
        message.setFromUserName(ToUserName);
        message.setToUserName(FromUserName);
        message.setCreateTime(new Date().getTime());
        message.setVoice(voice);
        message.setMsgType(MESSAGE_VOICE);
        return voiceMessageToxml(message);
    }

    /**
     * 将视频信息转为xml格式
     *
     * @param videoMessage 视频消息
     */
    public static String videoMessageToxml(VideoMessage videoMessage) {
        XStream xtream = new XStream();
        xtream.alias("xml", videoMessage.getClass());
        xtream.alias("Video", new Video().getClass());
        return xtream.toXML(videoMessage);
    }

    /**
     * 封装视频消息
     *
     * @param FromUserName 发送者
     * @param ToUserName   接受者
     * @param path         视频地址
     * @return
     */
    public static String initVideoMessage(String FromUserName, String ToUserName, String path) {
        Video video = new Video();
        video.setTitle("测试视频");
        video.setDescription("视频描述");
        video.setMediaId(getMediaId(path, MESSAGE_VIDEO));

        VideoMessage message = new VideoMessage();
        message.setFromUserName(ToUserName);
        message.setToUserName(FromUserName);
        message.setCreateTime(new Date().getTime());
        message.setVideo(video);
        message.setMsgType(MESSAGE_VIDEO);
        return videoMessageToxml(message);
    }

    /**
     * 将音乐信息转为xml格式
     *
     * @param musicMessage 音乐消息
     */
    public static String musicMessageToxml(MusicMessage musicMessage) {
        XStream xtream = new XStream();
        xtream.alias("xml", musicMessage.getClass());
        xtream.alias("Music", new Music().getClass());
        return xtream.toXML(musicMessage);
    }

    /**
     * 封装视频消息
     *
     * @param FromUserName 发送者
     * @param ToUserName   接受者
     * @param path         视频地址
     * @return
     */
    public static String initMusicMessage(String FromUserName, String ToUserName, String path) {
        Music music = new Music();
        music.setTitle("历历万乡");
        music.setDescription("视频描述");
        music.setMusicURL("http://vison.free.ngrok.cc/music/陈粒 - 历历万乡.mp3");
        music.setHQMusicUrl("http://vison.free.ngrok.cc/music/陈粒 - 历历万乡.mp3");
        music.setThumbMediaId(getMediaId(path, MESSAGE_THUMB));

        MusicMessage message = new MusicMessage();
        message.setFromUserName(ToUserName);
        message.setToUserName(FromUserName);
        message.setCreateTime(new Date().getTime());
        message.setMusic(music);
        message.setMsgType(MESSAGE_MUSIC);
        return musicMessageToxml(message);
    }


    /**
     * 获取Media
     *
     * @param path 文件地址
     * @param type 文件类型
     * @return
     */
    public static String getMediaId(String path, String type) {
        String accessToken = WeiXinUtil.getAccess_Token();
        String mediaId = null;
        try {
            mediaId = UploadUtil.upload(path, accessToken, type);
        } catch (KeyManagementException | NoSuchAlgorithmException
                | NoSuchProviderException | IOException e) {
            e.printStackTrace();
        }
        return mediaId;
    }
}
